昨天介紹完CNN的概念,今天要來實作模型,我看到有很多種寫法,會主要介紹測出來準確率最高的。
第一步就是先載入 MNIST 資料集,並將數據標準化到[0,1]範圍:
import tensorflow as tf
from tensorflow.keras import layers, models
mnist = tf.keras.datasets.mnist
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape((60000, 28, 28, 1)).astype('float32') / 255
x_test = x_test.reshape((10000, 28, 28, 1)).astype('float32') / 255
標籤轉換成 One-Hot Encoding:
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
建立 CNN 模型:
model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))
layers.Conv2D 是添加一個層,這個層主要用於處理二維數據。而 layers.MaxPooling2D 則是用於進行採樣,主要是縮小特徵圖的尺寸,同時保留重要的特徵,減少計算量。 layers.Flatten 用於將多維的輸入數據展平為一維數組,特別是用在將卷積層和全連接層結合時。 layers.Dense 主要功能是對輸入進行線性變換並應用激活函數,通常用於最後幾層,以進行分類或回歸任務。
建立好後就是編譯及訓練,最後評估:
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, batch_size=64, validation_split=0.1)
test_loss, test_acc = model.evaluate(x_test, y_test)
print('Test accuracy:', test_acc)
我會得到:
在這裡可以看到準確率高達99.04%,相較於之前不是用 CNN 做的 98.87%,有明顯提升。
如果我們想提高準確率還可以往這些方面思考:
1.增加卷積層和神經元
增加更多的卷積層或在全連接層中增加神經元可以提高模型的能力。
2.使用 Dropout
在全連接層中加入 Dropout 層會減少過擬合。
3.數據增強
訓練過程中進行數據增強,能夠提高模型的泛化能力。
4.調整超參數
可以嘗試不同的學習率和批次大小。